# coding=utf-8
import requests
import json
import config
import html
import re


class ZenTaoBusiness(object):
    """禅道用例库"""
    zt_base_url = config.ZENTAO_BASE_URL
    zt_user = config.ZENTAO_USER
    zt_password = config.ZENTAO_PASSWORD
    zt_headers = config.HEADERS
    config = config
    m = config.INTERFACE_URL.get('m')
    f = config.INTERFACE_URL.get('f')
    t = config.INTERFACE_URL.get('t')
    res_param = config.RESPONSE_PARAM
    
    @classmethod
    def get_session(cls):
        """获取会话
        :return:
        """
        r_session = requests.session()
        return r_session
    
    @classmethod
    def _query_params(cls, m, f, session_name, session_id):
        return {'m': m, 'f': f, 't': 'json', session_name: session_id}
    
    @classmethod
    def _query_params_new(cls, m, f, t, dy_params={}):
        params = dict({'m': m, 'f': f, 't': t})
        for x in dy_params.keys():
            params[x] = dy_params[x]
        return params
    
    @classmethod
    def zt_new_login(cls, r_session, name=None, password=None):
        """登陆禅道
        :param r_session:会话
        :param name:账号
        :param password:密码
        :return:
        """
        # 查询当前用户的数据
        if name and password:
            user_name = name
            user_password = password
        else:
            user_name = cls.zt_user
            user_password = cls.zt_password
        
        login_params = cls._query_params_new('user', 'login', 'json')
        response_url = r_session.get(cls.zt_base_url, params=login_params).url
        
        headers = cls.zt_headers
        headers['Referer'] = response_url
        
        body = {
            'account': user_name,
            'password': user_password,
            'keepLogin[]': 'on',
            'referer': '/zentao/',
            'verifyRand': 2035112972
        }
        
        login_response = r_session.post(url=response_url, data=body, headers=headers)
        if login_response.status_code != 200 or login_response.json()['status'] != 'success':
            raise Exception('账号:{},密码:{}登录失败，请检查'.format(user_name, user_password))
        return login_response.json()
    
    @classmethod
    def get_case_library(cls, r_session):
        """获取所有用例库
        :param r_session: 保持会话
        :return:dict{1:'a用例库'}
        """
        try:
            # 获取用例库接口param-objectID值固定
            prefix_param = cls._query_params_new(cls.m, cls.f, cls.t,
                                                 dy_params={'module': 'testsuite',
                                                            'method': 'library',
                                                            'objectID': 34})
            url = requests.get(cls.zt_base_url, prefix_param).url
            headers = cls.zt_headers
            headers['Referer'] = url
            # 请求获取用例库接口
            # s_data = r_session.get(url=url, headers=headers)
            s_data = r_session.get(url=cls.zt_base_url, params=prefix_param, headers=headers)
            if s_data.status_code == 200:
                s_data = json.loads(s_data.text)
                all_library = json.loads(s_data.get('data')).get('libraries')
                return all_library
            return None
        except Exception as e:
            print(str(e))
            return None
    
    @classmethod
    def according_name_find_ib(cls, library_name, r_session):
        """获取指定名字的用例库id
        :return:
        """
        try:
            library = cls.get_case_library(r_session)
            for l_id in library:
                if library[l_id].find(library_name) != -1:
                    return l_id
            return None
        except Exception as e:
            print(str(e))
            return None
    
    @classmethod
    def get_all_module_id(cls, lib_id, r_session):
        """获取指定用例库下所有模块
        :param lib_id: 用例库id
        :param r_session:
        :return:
        """
        try:
            prefix_param = cls._query_params_new(cls.m, 'browse', cls.t,
                                                 dy_params={'libID': lib_id, 'moduleID': 0})
            module_url = requests.get(cls.zt_base_url, prefix_param).url
            headers = cls.zt_headers
            headers['Referer'] = module_url
            res_module = r_session.get(url=cls.zt_base_url, headers=headers, params=prefix_param)
            if res_module.status_code == 200:
                s_module = json.loads(res_module.text)
                all_module = json.loads(s_module.get('data')).get(cls.res_param.get('module'))

                return all_module
            return {}
        except Exception as e:
            print(str(e))
            return {}
    
    @classmethod
    def according_module_name_find_id(cls, module_name, all_module, r_session, lib_id):
        """获取指定名字获取模块id
        :param module_name: 模块名称
        :param all_module: 所有模块
        :param lib_id: 所有模块
        :param r_session:
        :return:
        """
        try:
            if all_module is None:
                all_module = cls.get_all_module_id(lib_id, r_session)
            for m_id in all_module:
                if all_module[m_id] == module_name:
                    return m_id
            return None
        except Exception as e:
            print(str(e))
    
    def add_modules(self, r_session, module_name, lib):
        """添加用例库模块
        :return:
        """
        # BYT新增，只新增前三层的模块名称
        module_name='/'.join(module_name.split('/')[:4])
        # 拆解模块
        all_modules_name = module_name.split('/')[1:]
        module_id = i = 0
        while True:
            # 获取模块下所有子模块
            all_modules = self.object.get_zt_modules(r_session, lib, module_id)
            if i >= len(all_modules_name):
                return module_id
            # 查询模块是否存在，不存在则添加
            if all_modules.get(all_modules_name[i]) is None:
                # 添加模块
                self.object.add_lib_modules(r_session, all_modules_name[i], lib, module_id)
            else:
                module_id = all_modules.get(all_modules_name[i])
                i += 1
    
    @classmethod
    def get_zt_modules(cls, r_session, lib, modules_id):
        """获取禅道用例库的一级模块名
        :return:
        """
        if modules_id:
            prefix_param = cls._query_params_new('tree', 'browse', cls.t,
                                                 dy_params={'rootID': lib,
                                                            'viewType': 'caselib',
                                                            'moduleID': modules_id,
                                                            'branch': 0})
        else:
            prefix_param = cls._query_params_new('tree', 'browse', cls.t,
                                                 dy_params={'libID': lib, 'view': 'caselib'})
        case_url = requests.get(cls.zt_base_url, prefix_param).url
        headers = cls.zt_headers
        headers['Referer'] = case_url
        res = r_session.get(url=cls.zt_base_url, params=prefix_param, headers=headers)
        if res.status_code == 200:
            data = json.loads(json.loads(res.text).get('data')).get('sons')
            zt_first_modules = {d.get('name'): d.get('id') for d in data}
            return zt_first_modules
    
    @classmethod
    def add_lib_modules(cls, r_session, name, lib, modules_id=None):
        """添加用例库的模块
        :param r_session:
        :param name: 模块名称
        :param lib: 用例库id
        :param modules_id: 模块id
        :return:
        """
        if modules_id:
            prefix_param = cls._query_params_new('tree', 'manageChild', 'json',
                                                 dy_params={'root': lib, 'viewType': 'caselib',
                                                            'moduleID': modules_id, 'branch': 0})
        else:
            prefix_param = cls._query_params_new('tree', 'manageChild', 'json',
                                                 dy_params={'root': lib, 'viewType': 'caselib'})
        
        add_modules_url = requests.get(cls.zt_base_url, prefix_param).url
        headers = cls.zt_headers
        headers['Referer'] = add_modules_url
        
        add_modules_data = {
            'modules[]': name,
            'shorts[]': '',
            'parentModuleID': modules_id
        }
        res = r_session.post(url=cls.zt_base_url, headers=headers, params=prefix_param,
                             data=add_modules_data)
        if res.status_code == 200:
            return res.text
    
    @classmethod
    def get_zt_case_add_front_data(cls, import_type, lib):
        """获取禅道用例添加用例前置数据-用例库-用例
        :return:
        """
        if import_type == '1':
            prefix_param = cls._query_params_new(cls.m, 'createCase', cls.t,
                                                 dy_params={'libID': lib, 'moduleID': 0})
        else:
            prefix_param = cls._query_params_new('testcase', 'create', cls.t,
                                                 dy_params={'productID': lib, 'moduleID': 0,
                                                            'branch': 0})
        case_url = requests.get(cls.zt_base_url, prefix_param).url
        headers = cls.zt_headers
        headers['Referer'] = case_url
        return {'prefix_param': prefix_param, 'case_url': case_url, 'headers': headers}
    
    @classmethod
    def new_zt_case_sync(cls, r_session, case_data, zt_data):
        """禅道用例库同步用例-同步
        :return:
        """
        try:
            res_case = r_session.post(url=cls.zt_base_url, data=case_data,
                                      params=zt_data.get('prefix_param'),
                                      headers=zt_data.get('headers'))
            if res_case.status_code == 200:
                if res_case.text.find("alert") != -1:
                    text = res_case.text.split("alert('")[1].split("')\n")[0]
                    case_id = res_case.text.split('caseID=')[1].split('\'')[0]
                    err = {'text: ': text, 'case_id: ': case_id}
                    print(err)
        except Exception as e:
            print(str(e))
    
    @staticmethod
    def handle_colon(content, word):
        """处理冒号
        :param content:
        :param word:
        :return:
        """
        # 英文:
        if content.find('{}:'.format(word)) != -1:
            symbol = ':'
        # 中文：
        elif content.find('{}：'.format(word)) != -1:
            symbol = '：'
        else:
            symbol = ''
        data = content.split('{}{}'.format(word, symbol))[1]
        return data
    
    @classmethod
    def key_word(cls, case_content):
        """处理关键词
        :param case_content:
        :return:
        """
        # 用例库名称或者用例名称
        case_title = case_content.split('-')[0]
        key_word = story = ''
        for filed in case_content.split('-')[1:]:
            if filed.find('关键词') != -1:
                key_word = cls.handle_colon(filed, '关键词')
            if filed.find('需求') != -1:
                story = cls.handle_colon(filed, '需求')
        return case_title, key_word, story
